#include "FitsConverter.h"
#include <valarray>
#include <sstream>

/*
功能说明：
FitsConverter 类用于将多个 bin 文件（假定为 512x512 的 16 位无符号整型图像数据）合并写入一个 FITS 文件。
每个 bin 文件的数据会作为一个扩展（extension）保存到 FITS 文件中，并在 FITS 文件头中记录每个 bin 文件的名字和文件生成时间。

示例用法：
int main() {
    // 假设每个 bin 文件是 512x512 的 16 位无符号整型图像
    std::vector<std::vector<uint16_t>> binData;
    std::vector<std::string> binNames;
    // 填充 binData 和 binNames ...
    FitsConverter converter("output.fits");
    converter.setBinFiles(binData, binNames);
    converter.writeFits();
    return 0;
}

编译脚本(CCfits 和 cfitsio已安装）：
g++ main.cpp FitsConverter.cpp -I/path/to/CCfits/include -L/path/to/CCfits/lib -lCCfits -lcfitsio -o myprog

// 其中 /path/to/CCfits/include 和 /path/to/CCfits/lib 需替换为实际路径
*/

FitsConverter::FitsConverter(const std::string& fitsFileName)
    : fitsFileName_(fitsFileName) {
    for (size_t i = 0; i < kNumBins; ++i) binData_[i] = nullptr;
}

FitsConverter::~FitsConverter() {
    for (size_t i = 0; i < kNumBins; ++i) {
        delete[] binData_[i];
        binData_[i] = nullptr;
    }
}

void FitsConverter::allocateData(size_t width, size_t height) {
    width_ = width;
    height_ = height;
    for (size_t i = 0; i < kNumBins; ++i) {
        delete[] binData_[i];
        binData_[i] = new uint16_t[width_ * height_];
        std::fill(binData_[i], binData_[i] + width_ * height_, 0);
    }
}

void FitsConverter::updateBinData(size_t index, const uint16_t* data, size_t dataSize) {
    if (index >= kNumBins || !binData_[index] || dataSize != width_ * height_) return;
    std::copy(data, data + dataSize, binData_[index]);
}

void FitsConverter::setBinName(size_t index, const std::string& name) {
    if (index < kNumBins) binNames_[index] = name;
}

bool FitsConverter::writeFits() {
    std::unique_ptr<CCfits::FITS> fitsOut(new CCfits::FITS(fitsFileName_, USHORT_IMG, 0, nullptr));
    writeHeader(*fitsOut);
    writeDataExtensions(*fitsOut);
    return true;
}

void FitsConverter::writeHeader(CCfits::FITS& fits) {
    std::time_t t = std::time(nullptr);
    char buf[64];
    std::strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", std::localtime(&t));
    fits.pHDU().addKey("DATE", std::string(buf), "File creation date");
    for (size_t i = 0; i < kNumBins; ++i) {
        std::ostringstream key;
        key << "BIN" << (i+1) << "NAME";
        fits.pHDU().addKey(key.str(), binNames_[i], "Bin file name");
    }
}

void FitsConverter::writeDataExtensions(CCfits::FITS& fits) {
    for (size_t i = 0; i < kNumBins; ++i) {
        std::vector<long> axes = {static_cast<long>(width_), static_cast<long>(height_)};
        std::string extName = "BIN" + std::to_string(i+1);
        fits.addImage(extName, USHORT_IMG, axes);
        CCfits::ExtHDU& ext = fits.extension(extName);
        std::valarray<uint16_t> arr(binData_[i], width_ * height_);
        ext.write(1, width_ * height_, arr);
    }
} 